#include "pd_TCPserver.hpp"

/*************************************   CONSTANTS  *************************************/
static const int TCPPORT = 8071;

/*
 * init TCP server
 * para: int* ts: tcp server listen Fd
 * return: bool if ok true else false
 * 
 */
bool initTCPserver(int* ts){
    struct sockaddr_in servaddr;
    if( ((*ts) = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
        printf("initTCPserver %d: create socket error: %s(errno: %d)\n", getpid(), strerror(errno), errno);
        return false;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(TCPPORT);

    if( bind((*ts), (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("initTCPserver %d: bind socket error: %s(errno: %d)\n", getpid(), strerror(errno), errno);
        return false;
    }
    if( listen((*ts), 10) == -1){   //TCP 连接队列：最大客户端连接数量
        printf("initTCPserver %d: listen socket error: %s(errno: %d)\n", getpid(), strerror(errno), errno);
        return false;
    }
    return true;
}

/*
 * wait connect of TCP forever!
 * exec: listen/recv/send/close
 * para: int listenFd
 * return: none
 */
void waitConnect(int listenFd){		
	printf("waitConnect %d: wait for accept\n", getpid());
	
	int connfd = accept(listenFd, (struct sockaddr*)NULL, NULL);
	if (connfd == -1){
		if (errno == EINTR)
		{
			printf("waitConnect %d: accept socket error: EINTR\n", getpid());
			return;
		}
		else{
			printf("waitConnect %d: accept socket error: %s(errno: %d)\n", getpid(), strerror(errno), errno);
			return;
		}
	}
	else{
		printf("waitConnect %d: get TCP client connect, client Id is:%d\n", getpid(), connfd);
		workerExec(connfd);  //recv and send
		close(connfd);  //parent close connfd in the very beginning
	}
}

/*
 * close TCP server
 * para: int fd: tcp server listen Fd
 * return: none
 */
void closeTCPserver(int fd){
	close(fd);
}

/*
 * main
 * para: none
 * return 0 normal, 1 fatal error, other undifined
 */
int main(){
	//change workdirectory
	if (chdir(WORKDIR.c_str())) exit(2);
	
	int listenFd;
	if (!initTCPserver(&listenFd)) exit(1);
	
	while(1){
		waitConnect(listenFd);
	}
	closeTCPserver(listenFd);
	return 0;
}
